package vip.specimen.system.controller.authorization;

import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import vip.specimen.system.datasource.entity.SystemUserEntity;
import vip.specimen.system.datasource.validation.SystemLoginValidation;
import vip.specimen.system.datasource.validation.SystemUserEditPasswordValidation;
import vip.specimen.system.service.SystemUserService;
import vip.specimen.system.utils.CommonUtil;
import vip.specimen.system.utils.VerificationCodeUtil;
import vip.specimen.system.common.enums.ResultCode;
import vip.specimen.system.result.JsonResult;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

/**
 * *@Author: 余浪人
 * *@Date：2021/2/25 10:09
 * *@Email:yulangren520@Gmail.com
 * *@QQ:1368419640
 **/
@Api(tags = "用户授权")
@RestController
@RequestMapping(value = "/verificationCode")
public class UserAuthorizationController {
    @Value("${system.verification.key}")
    String key;
    @Value("${system.verification.expire}")
    long expire;
    @Resource
    private SystemUserService userService;

    /**
     * 账号登录
     *
     * @param login   登录体
     * @param request 请求
     * @return res
     */
    @PostMapping(value = "account")
    @ApiOperation(value = "账号登录", notes = "账号登录接口")
    public JsonResult account(@RequestBody @Valid SystemLoginValidation login, HttpServletRequest request) {
        VerificationCodeUtil v = new VerificationCodeUtil(this.key, CommonUtil.getIp(request), this.expire);
        if (!v.codeIsExist(login.getVerifCode())) {
            return JsonResult.failed(ResultCode.DATA_VALIDATION_CODE_FAIL);
        }
        Subject subject = SecurityUtils.getSubject();
        try {
            UsernamePasswordToken token = new UsernamePasswordToken(login.getUsername(), login.getPassword());
            subject.login(token);
            userService.updateLogin(this.userService.findByUsername(login.getUsername()), CommonUtil.getIp(request));
            JSONObject json = new JSONObject(2);
            json.put("account_token", subject.getSession().getId().toString());
            json.put("expires_in", subject.getSession().getTimeout());
            return JsonResult.success(json);
        } catch (IncorrectCredentialsException e) {
            return JsonResult.failed(ResultCode.DATA_VALIDATION_PASSWORD_FAIL);
        } catch (AuthenticationException e) {
            return JsonResult.failed(ResultCode.DATA_VALIDATION_USER_FAIL);
        }
    }

    /**
     * 用户登录认证失败
     *
     * @return 为登录提示
     */
    @ApiIgnore
    @GetMapping
    public JsonResult auth() {
        return JsonResult.failed(ResultCode.ERROR_NOT_LOGIN);
    }

    /**
     * 没有权限
     *
     * @return 没有权限提示信息
     */
    @ApiIgnore
    @GetMapping("notPermission")
    public JsonResult notPermission() {
        return JsonResult.failed(ResultCode.ERROR_NOT_PERMISSION);
    }


    /**
     * 获取用户信息
     *
     * @return 用户对象
     */
    @GetMapping(value = "userInfo")
    @ApiOperation(value = "查看信息", notes = "获取当前用户的全部信息")
    public JsonResult<SystemUserEntity> userInfo() {
        SystemUserEntity user = (SystemUserEntity) SecurityUtils.getSubject().getPrincipal();
        if (null != user) {
            user.setPassword(null);
            user.setSalt(null);
            user.setId(null);
            return JsonResult.success(user);
        }
        return JsonResult.failed(ResultCode.ERROR_NOT_LOGIN);
    }

    /**
     * 用户注销
     *
     * @return null
     */
    @GetMapping(value = "logout")
    @ApiOperation(value = "注销退出", notes = "用户注销")
    public JsonResult logout() {
        SystemUserEntity userEntity = (SystemUserEntity) SecurityUtils.getSubject().getPrincipal();
        if (null == userEntity || null == userEntity.getUuid()) return JsonResult.failed(ResultCode.INVALID_OPERATION);
        SecurityUtils.getSubject().logout();
        return JsonResult.success();
    }

    /**
     * 修改密码
     *
     * @param passwordValidation 验证
     * @return 用户
     */
    @PostMapping("password")
    @RequiresPermissions(value = "user:update:password")
    @ApiOperation(value = "更新密码", notes = "根据实体修改当前登录用户的密码")
    public JsonResult updatePassword(@RequestBody @Valid SystemUserEditPasswordValidation passwordValidation) {
        SecurityUtils.getSubject().logout();
        return JsonResult.success(this.userService.updatePassword(passwordValidation));
    }
}